/**
  ******************************************************************************
  * @file           : XYXKC_ML307R.cpp
  * @author         : admin
  * @brief          : None
  * @attention      : None
  * @date           : 2025/1/15
  ******************************************************************************
  */

#include "XYXKC_ML307R.h"
unsigned int getMqttStateTime;
XYXKC_ML307R *ml307RThis;
XYXKC_ML307R::XYXKC_ML307R():_ML307R_Serial(){
    ml307RThis = this;
    getMqttStateTime = 0;
}
XYXKC_ML307R::~XYXKC_ML307R(){
    ml307RThis = NULL;
}

static void ml307r_Task(void *p){
    while(true){
        ml307RThis->ML307R_loop();
        delay(10);
        yield();
    }
}
void XYXKC_ML307R::_delayInit(){
    while(true){
        _ML307R_Serial_println_look("AT+CGMR");
        delay(1000);
        if (_ML307R_Serial.available()) {
            String _ML307R_Serial_msg = _ML307R_Serial.readString();
            Serial.println(_ML307R_Serial_msg);
            if((String(_ML307R_Serial_msg).indexOf(String("OK")) != -1)){
                break;
            }
        }
    }
    xTaskCreatePinnedToCore(ml307r_Task,  "ml307r_Task",  2048,  this,  1,  NULL,  ARDUINO_RUNNING_CORE);
}

void XYXKC_ML307R::begin(SoftwareSerial *serial){
    _ML307R_Serial.begin(serial,XYXKC_ML307R_BAUD_RATE);
    _delayInit();

}
void XYXKC_ML307R::begin(HardwareSerial *serial){
    _ML307R_Serial.begin(serial,XYXKC_ML307R_BAUD_RATE);
    _delayInit();
}
void XYXKC_ML307R::begin(HardwareSerial *serial,int rxPin,int txPin){
    _ML307R_Serial.begin(serial,rxPin,txPin,XYXKC_ML307R_BAUD_RATE);
    _delayInit();

}

void XYXKC_ML307R::_ML307R_Serial_println_look(String msg){
    while(_ML307R_look);
    _ML307R_look = true;
    _ML307R_Serial.println(msg);
    _ML307R_look = false;
    delay(20);
}
void XYXKC_ML307R::mqttBegin(const String username,const String password,const String server){
    String mqttId = "";
    for(int i=0;i < 15;i++){
        mqttId += String(random(0,10));
    }
    _ML307R_Serial_println_look("AT+MQTTCONN=0,\""+server+"\",1883,\""+mqttId+"\",\""+username+"\",\""+password+"\"");

}

void XYXKC_ML307R::mqttBegin(const String username,const String password){
    mqttBegin(username,password,"43.139.167.119");
}

void XYXKC_ML307R::mqttStop(){
    _ML307R_Serial_println_look("AT+MQTTDISC=0");
}
void XYXKC_ML307R::mqttSubscribe(String topic,enum XYXKC_ML307R_QOS QOS){
    if(find(_topics.begin(),_topics.end(),topic) == _topics.end()){
        _topics.push_back(topic);
    }
    _ML307R_Serial_println_look("AT+MQTTSUB=0,\""+topic+"\","+String(QOS));
}
void XYXKC_ML307R::mqttPublish(String topic,String message,enum XYXKC_ML307R_QOS QOS){
    _ML307R_Serial_println_look("AT+MQTTPUB=0,\""+topic+"\","+String(QOS)+",0,0,"+String(message).length()+",\""+message+"\"");
    delay(30);
}
void XYXKC_ML307R::_getMqttState(){
    if(!_ML307R_look && millis() - getMqttStateTime > 20){
        getMqttStateTime = millis();
        _ML307R_look = true;
        _ML307R_Serial.println("AT+MQTTSTATE=0");
        _ML307R_look = false;
    }

}
bool XYXKC_ML307R::isMqttConnectionSuccessful() {
    return _mqttState == connectionSuccessful;
}

void XYXKC_ML307R::setMqttMsgCallback(const String topic,const topicMsgFun funName){
    if(find(_topicFunArray.begin(),_topicFunArray.end(),topic) == _topicFunArray.end()){
        _topicFunArray.push_back(topic);
        _topicMsgFunArray.push_back(funName);
    }
}
/**
 * 获取对应标签的字符串
 * */
static String getTagString(String message,String label){
    int tagStart = message.indexOf(label);
    String tagMsg = message.substring(tagStart,-1);
    int tagStop = tagMsg.indexOf("\r\n");
    return tagMsg.substring(0,tagStop);
}
/**
 * 用来获取mqtt状态
 * */

static int state(String message){
    message = getTagString(message,"+MQTTSTATE:");
    int stateIndex = message.indexOf(":")+2;
    return message.substring(stateIndex,stateIndex+1).toInt();
}

/**
 *字符串切割成数组
 */
static void splitString(String input, char delimiter, String tokens[],int length) {
    int tokenCount = 0;
    int startIndex = 0;
    int endIndex;

    while ((endIndex = input.indexOf(delimiter, startIndex)) != -1 && tokenCount < length-1) {
        tokens[tokenCount] = input.substring(startIndex, endIndex);
        tokenCount++;
        startIndex = endIndex + 1;
    }
    if (startIndex < input.length()) {
        tokens[tokenCount] = input.substring(startIndex);
        tokenCount++;
    }
}
void XYXKC_ML307R::ML307R_loop(){
    if (_ML307R_Serial.available()) {
        String _ML307R_Serial_msg = _ML307R_Serial.readString();
        if((String(_ML307R_Serial_msg).indexOf(String("+MQTTSTATE:")) != -1)){
            //如果连接成功订阅主题
            uint8_t _state = state(_ML307R_Serial_msg);
            if(_state != _mqttState && _state == connectionSuccessful){
                for(int i=0; i < _topics.size(); i++){
                    mqttSubscribe(_topics[i]);
                }
            }
            _mqttState = _state;
        }
        //解析接收的消息
        if((String(_ML307R_Serial_msg).indexOf(String("+MQTTURC: \"publish\"")) != -1)){
            String publishData[7];
            String publishMsg = getTagString(_ML307R_Serial_msg,"+MQTTURC: \"publish\"");
            splitString(publishMsg,',',publishData,sizeof(publishData) /sizeof(publishData[0]));
            //去掉两边的双引号
            String topic = publishData[3].substring(1, publishData[3].length()-1);
            for(int i=0;i < _topicFunArray.size();i++){

                if(_topicFunArray[i] == topic){
                    _topicMsgFunArray[i](publishData[6]);
                    break;
                }
            }
        }
    }
    else{
        _getMqttState();
    }
}